package com.jrx.anytxn.param.service.product.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jrx.anytxn.common.constant.CommonContants;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.i18n.response.TxnPage;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.constant.ErrorMsgConstant;
import com.jrx.anytxn.param.dto.product.PrWaiveInterestTableReq;
import com.jrx.anytxn.param.dto.product.PrWaiveInterestTableRes;
import com.jrx.anytxn.param.entity.PrWaiveInterestTable;
import com.jrx.anytxn.param.mapper.ext.ExtPrWaiveInterestTableMapper;
import com.jrx.anytxn.param.service.product.IPrWaiveInterestTableService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
 * 贴息利率表  业务接口实现
 *
 * @author yf
 * date 2020/2/24 0024
 * @version V1.0
 **/
@CacheConfig(cacheNames = "WAIVE_INTEREST")
@Service
public class PrWaiveInterestTableServiceImpl implements IPrWaiveInterestTableService {

    private static final Logger logger = LoggerFactory.getLogger(PrWaiveInterestTableServiceImpl.class);

    @Resource
    private ExtPrWaiveInterestTableMapper extPrWaiveInterestTableMapper;

    @Autowired
    private ISegmentService segmentService;

    @Override
    public PrWaiveInterestTableRes findByTenIdAndInterestId(String tenantId, String interestId) throws TxnException {
        if (StringUtils.isBlank(tenantId) || StringUtils.isBlank(interestId)) {
            logger.error(TxnRespCode.NOT_EMPTY.getMsg());
            throw new TxnException(TxnRespCode.NOT_EMPTY.getMsg());
        }
        PrWaiveInterestTable prWaiveInterestTable = extPrWaiveInterestTableMapper.selectByTenIdAndInterestId(tenantId, interestId);
        return BeanMapping.copy(prWaiveInterestTable, PrWaiveInterestTableRes.class);
    }

    @Override
    public TxnPage<PrWaiveInterestTableRes> findAllPageByTenId(Integer pageNum, Integer pageSize, String tenantId) throws TxnException {
        Page<PrWaiveInterestTable> page = PageHelper.startPage(pageNum, pageSize, Constant.ORDER_BY_SORT);
        List<PrWaiveInterestTable> waiveInterestTableList = extPrWaiveInterestTableMapper.selectByTenId(tenantId);
        if (waiveInterestTableList.isEmpty()) {
            logger.error("查询贴息利率表为空");
            throw new TxnException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
        }
        List<PrWaiveInterestTableRes> res = BeanMapping.copyList(waiveInterestTableList, PrWaiveInterestTableRes.class);
        return new TxnPage<>(pageNum, pageSize, page.getTotal(), res);
    }

    @Override
    public PrWaiveInterestTableRes addWaiveInterestTable(PrWaiveInterestTableReq prWaiveInterestTableReq) throws TxnException {
        PrWaiveInterestTable prWaiveInterestTable = extPrWaiveInterestTableMapper.selectByTenIdAndInterestId(prWaiveInterestTableReq.getTenantId(), prWaiveInterestTableReq.getInterestId());
        if (prWaiveInterestTable != null) {
            logger.error(TxnRespCode.DATA_EXISTS.getMsg());
            throw new TxnException(TxnRespCode.DATA_EXISTS.getMsg());
        }
        PrWaiveInterestTable waiveInterestTable = BeanMapping.copy(prWaiveInterestTableReq, PrWaiveInterestTable.class);
        try {
            waiveInterestTable.setId(segmentService.getId(Constant.PR_WAIVE_INTEREST_TABLE));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnException(ErrorMsgConstant.ERROR_ID);
        }
        waiveInterestTable.setRecordVersionNumber(Constant.VERSION_NUMBER);
        extPrWaiveInterestTableMapper.insertSelective(waiveInterestTable);
        return BeanMapping.copy(waiveInterestTable, PrWaiveInterestTableRes.class);
    }

    @CacheEvict(key="'waiveInterest_'+#prWaiveInterestTableReq.tenantId+'_'+#prWaiveInterestTableReq.interestId")
    @Override
    public PrWaiveInterestTableRes modifyWaiveInterestTable(PrWaiveInterestTableReq prWaiveInterestTableReq) throws TxnException {
        PrWaiveInterestTable prWaiveInterestTable = extPrWaiveInterestTableMapper.selectByTenIdAndInterestId(prWaiveInterestTableReq.getTenantId(), prWaiveInterestTableReq.getInterestId());
        if (prWaiveInterestTable == null) {
            logger.error(TxnRespCode.NO_DATA.getMsg());
            throw new TxnException(TxnRespCode.NO_DATA.getMsg());
        }
        PrWaiveInterestTable waiveInterestTable = BeanMapping.copy(prWaiveInterestTableReq, PrWaiveInterestTable.class);
        // 更新
        extPrWaiveInterestTableMapper.updateByTenIdAndInterestId(waiveInterestTable);
        return BeanMapping.copy(waiveInterestTable, PrWaiveInterestTableRes.class);
    }

    @CacheEvict(key="'waiveInterest_'+#tenantId+'_'+#interestId")
    @Override
    public Boolean removeByTenIdAndInterestId(String tenantId, String interestId) throws TxnException {
        if (StringUtils.isBlank(tenantId) || StringUtils.isBlank(interestId)) {
            logger.error(TxnRespCode.NOT_EMPTY.getMsg());
            throw new TxnException(TxnRespCode.NOT_EMPTY.getMsg());
        }
        int i = extPrWaiveInterestTableMapper.deleteByTenIdAndInterestId(tenantId, interestId);
        return i > 0;
    }

    @Cacheable(key="'waiveInterest_'+#tenantId+'_'+#interestId")
    @Override
    public PrWaiveInterestTable findWaiveInterestByInterestId(String interestId, String tenantId) throws TxnException {
        PrWaiveInterestTable prWaiveInterestTable = extPrWaiveInterestTableMapper.selectByTenIdAndInterestId(tenantId, interestId);
        if (prWaiveInterestTable == null) {
            logger.error(TxnRespCode.NO_DATA.getMsg());
            throw new TxnException(TxnRespCode.NO_DATA.getMsg());
        }
        return prWaiveInterestTable;
    }

    /**
     * 日利率计算
     *
     * @param prWaiveInterestTable 利率信息
     * @param businessDate         当前业务日期
     * @return 日利率
     */
    @Override
    public BigDecimal getWaiveDailyRate(PrWaiveInterestTable prWaiveInterestTable, Date businessDate) {
        BigDecimal baseRate = prWaiveInterestTable.getBaseRate();// 初始利率 若是月则不需要复杂计算

        //年利率基础参数
        int yearBase = getYearBase(prWaiveInterestTable.getYearBase());

        // 月利率基础参数
        int monthBase = getMonthBase(prWaiveInterestTable.getMonthBase(), businessDate);

        // 0-年利率
        if (Constant.INT_TYPE_YEAR.equalsIgnoreCase(prWaiveInterestTable.getRateType())) {//初始是年利率
            baseRate = baseRate.divide(
                    BigDecimal.valueOf(yearBase), CommonContants.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);
        } else if (Constant.INT_TYPE_MONTH.equalsIgnoreCase(prWaiveInterestTable.getRateType())) {// 初始是月利率
            baseRate = baseRate.divide(
                    BigDecimal.valueOf(monthBase), CommonContants.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);
        }
        return baseRate;
    }

    /**
     * 年利率计算
     *
     * @param prWaiveInterestTable 利率信息
     * @return 年利率
     */
    @Override
    public BigDecimal getYearRate(PrWaiveInterestTable prWaiveInterestTable) {

        BigDecimal baseRate = prWaiveInterestTable.getBaseRate();// 初始利率 若是年则不需要复杂计算

        //年利率基础参数
        int yearBase = getYearBase(prWaiveInterestTable.getYearBase());

        if (Constant.INT_TYPE_MONTH.equalsIgnoreCase(prWaiveInterestTable.getRateType())) {// 若初始是月利率
            baseRate = baseRate.multiply(new BigDecimal(CommonContants.MONTH));
        } else if (Constant.INT_TYPE_DAILY.equalsIgnoreCase(prWaiveInterestTable.getRateType())) {//初始是日利率
            baseRate = baseRate.multiply(new BigDecimal(yearBase));
        }
        return baseRate;
    }

    /**
     * 获取年利率基础天数
     *
     * @param yearBaseParam 年利率基础因子
     * @return 年利率基础天数
     */
    private int getYearBase(String yearBaseParam) {
        switch (yearBaseParam) {
            case Constant.YEAR_360:
                return 360;
            case Constant.YEAR_366:
                GregorianCalendar gc = new GregorianCalendar();
                if (gc.isLeapYear(gc.get(GregorianCalendar.YEAR))) {
                    return 366;
                } else {
                    return 365;
                }
            default:
                return 365;
        }
    }

    /**
     * 获取年利率基础天数
     *
     * @param monthBaseParam 年利率基础因子
     * @return 年利率基础天数
     */
    private int getMonthBase(String monthBaseParam, Date businessDate) {
        switch (monthBaseParam) {
            case Constant.MONTH_BASE_D:
                return DateUtils.getTotalDaysOfMonth(businessDate);
            default:
                return 30;
        }
    }

}
